/**
 * @Author:  renyc
 * @Date: 2022-11-30 14:43:29
 */
'use strict';

import Util from "../utils/Util.js"
import Viewer from "../viewer/Viewer";
import LayerType from "./LayerType.js";
import {LayerEvent} from "../event/LayerEvent.js";
import Overlay from "../overlay/Overlay";
import {LayerEventType, OverlayEventType} from "../event/EventType.js";
import EventFactory from "../event/EventFactory.js";

// const LAYER_OPTS {
//     id     : undefined,         //Layer的id
//     source : undefined,         //Layer的数据源    
// }

/**
 * Layer类
 * 定义Layer的通用属性、接口和实现
 * Layer的派生类实现Override函数，形成具备完整功能的Layer
 */
class Layer{

    constructor(name, options){
        //若options为定义，则定义一个空的options
        options = options || {};

        //Layer属性
        this._id = options.id || Util.uuid();
        this._name = name || this._id;
        this._type = LayerType.NONE;            //图层类型
        this._source = options.source;          //图层的数据源

        /** 
         * _delegate是Layer的实际数据内容
         * 不同Layer的this._delegate的所指向的内容不同，this._delegate的值由子类赋值
         */
        this._delegate = undefined;             //Layer的Cesium对象
        this._viewer = undefined;               //Viewer对象

        //Layer状态
        this._show = false;                     //图层是否显示

        //Layer数据 
        this._cache = {}                        //Cesium的数据缓存

        //Layer事件
        //this._event = new LayerEvent();         //图层事件
        this._event = EventFactory.createLayerEvent();
    }

    /**
     * 获取Layer的ID
     */
    get id(){
        return this._id;
    }

    /**
     * 获取Layer的name
     */
    get name(){
        return this._name;
    }

    /**
     * 返回图层类型
     */
    get type(){
        return this._type;
    }

    get source(){
        return this._source;
    }

    get delegate(){
        return this._delegate;
    }

    /**
     * @description 图层渲染函数
     * @override
     */
    render(){}

    /**
     * 注册Layer事件监听
     * @param {*} type 
     * @param {*} listener 
     */
    on(type, listener){
        return this._event.on(type, listener, this);
    }

    /**
     * 注销Layer事件监听
     * @param {*} type 
     * @param {*} listener 
     */
    off(type, listener){
        return this._event.off(type, listener, this);
    }

    /**
     * 触发Layer事件
     * @private
     * @param {*} type 
     * @param {*} params 
     * @returns this
     */
    _fire(type, params) {
        this._event.fire(type, params)
        return this;
    }

    /**
     * 将Layer挂载到Viewer上
     *
     * @Override 
     * @param {Viewer} viewer 
     */
    attach(viewer){
        this._viewer = viewer;      //记录当前Layer所属的viewer
        // if(!this._delegate){
        //     return;
        // }
        this._attach();
        //触发LayerEventType.ADD事件
        this._fire(LayerEventType.ADD, {obj:this});
    }

    /**
     * 将Layer从Viewer上卸载
     * @Override
     */
    detach(){
        //触发LayerEventType.REMOVE事件
        this._fire(LayerEventType.REMOVE, {obj:this});

        this._detach();
        this._viewer = undefined;        
    }

    /**
     * 将Layer挂载到Viewer上(内部方法)
     * 由子类实现该函数
     * @protected
     * @Override
     */
    _attach(){}

    /**
     * 将Layer从Viewer上卸载(内部方法)
     * 由子类实现该函数
     * @protected
     * @Override
     */
    _detach(){}

    /**
     * 向Layer上添加Overlay
     * @param {Overlay} overlay 
     * @returns {boolean}
     */
    addOverlay(overlay){
        if(!overlay){
            return false;
        }
        let ret = false;
        if(!this._cache.hasOwnProperty(overlay.id)){
            // if(this._delegate){
            //     overlay.attach(this);
            //     this._cache[overlay.id] = overlay;
            // }
            if(overlay.attach(this)){
                this._cache[overlay.id] = overlay;
            }
        }

        return ret;
    }

    /**
     * 删除图层上的Overlay
     * @param {Overlay} overlay 
     */
    removeOverlay(overlay){
        if(!overlay){
            return false;
        }
        let ret = false;
        if(this._cache.hasOwnProperty(overlay.id)){
            overlay.detach();
            delete this._cache[overlay.id];
        }

        return ret;
    }

    getOverlayById(id){
        return this._cache[id];
    }
}

export default Layer
